/*******************************************************************************************************************************
* @brief	GPIO pin interrupt driver
*
*
********************************************************************************************************************************
* @attention
*
* THE PRESENT FIRMWARE WHICH IS FOR GUIDANCE ONLY AIMS AT PROVIDING CUSTOMERS WITH CODING INFORMATION 
* REGARDING THEIR PRODUCTS IN ORDER FOR THEM TO SAVE TIME. AS A RESULT, SYNWIT SHALL NOT BE HELD LIABLE 
* FOR ANY DIRECT, INDIRECT OR CONSEQUENTIAL DAMAGES WITH RESPECT TO ANY CLAIMS ARISING FROM THE CONTENT 
* OF SUCH FIRMWARE AND/OR THE USE MADE BY CUSTOMERS OF THE CODING INFORMATION CONTAINED HEREIN IN CONN-
* -ECTION WITH THEIR PRODUCTS.
*
* COPYRIGHT 2012 Synwit Technology 
*******************************************************************************************************************************/
#include "SWM341.h"
#include "SWM341_exti.h"


/*******************************************************************************************************************************
* @brief	GPIO pin interrupt init
* @param	GPIOx is port of pin
* @param	n is pin number in port
* @param	mode can be EXTI_FALL_EDGE, EXTI_RISE_EDGE, EXTI_BOTH_EDGE, EXTI_LOW_LEVEL or EXTI_HIGH_LEVEL
* @return
*******************************************************************************************************************************/
void EXTI_Init(GPIO_TypeDef * GPIOx, uint32_t n, uint32_t mode)
{
	EXTI_Close(GPIOx, n);
	
	if(mode & 0x10)
	{
		GPIOx->INTLVLTRG |= (0x01 << n);			// level trigger
		
		if(mode & 0x01)
			GPIOx->INTRISEEN |= (0x01 << n);				// high level trigger
		else
			GPIOx->INTRISEEN &= ~(0x01 << n);				// low level trigger
	}		
	else
	{
		GPIOx->INTLVLTRG &= ~(0x01 << n);			// edge trigger
		
		if(mode & 0x02)
		{
			GPIOx->INTBE |= (0x01 << n);				// both edge trigger
		}
		else
		{
			GPIOx->INTBE &= ~(0x01 << n);				// single edge trigger
			
			if(mode & 0x01)
				GPIOx->INTRISEEN |= (0x01 << n);			// rising edge trigger
			else
				GPIOx->INTRISEEN &= ~(0x01 << n);			// falling edge trigger
		}
	}
	
	GPIOx->INTCLR = (1 << n);		// clear interrupt generated by configure
}

/*******************************************************************************************************************************
* @brief	GPIO pin interrupt enable
* @param	GPIOx is port of pin
* @param	n is pin number in port
* @return
*******************************************************************************************************************************/
void EXTI_Open(GPIO_TypeDef * GPIOx, uint32_t n)
{
	GPIOx->INTEN |= (0x01 << n);
}

/*******************************************************************************************************************************
* @brief	GPIO pin interrupt disable
* @param	GPIOx is port of pin
* @param	n is pin number in port
* @return
*******************************************************************************************************************************/
void EXTI_Close(GPIO_TypeDef * GPIOx, uint32_t n)
{
	GPIOx->INTEN &= ~(0x01 << n);
}

/*******************************************************************************************************************************
* @brief	GPIO pin interrupt state query
* @param	GPIOx is port of pin
* @param	n is pin number in port
* @return	1 interrupt happened, 0 interrupt not happen
*******************************************************************************************************************************/
uint32_t EXTI_State(GPIO_TypeDef * GPIOx, uint32_t n)
{
	return (GPIOx->INTSTAT >> n) & 0x01;
}

/*******************************************************************************************************************************
* @brief	GPIO pin interrupt raw state query, used when this interrupt disabled
* @param	GPIOx is port of pin
* @param	n is pin number in port
* @return	1 interrupt condition happened, 0 interrupt condition not happen
*******************************************************************************************************************************/
uint32_t EXTI_RawState(GPIO_TypeDef * GPIOx, uint32_t n)
{
	return (GPIOx->INTRAWSTAT >> n) & 0x01;
}

/*******************************************************************************************************************************
* @brief	GPIO pin interrupt clear
* @param	GPIOx is port of pin
* @param	n is pin number in port
* @return
*******************************************************************************************************************************/
void EXTI_Clear(GPIO_TypeDef * GPIOx, uint32_t n)
{
	GPIOx->INTCLR = (0x01 << n);
}
